﻿#include "DialogCameraSetup.h"
#include "ui_DialogCameraSetup.h"
#include <QDebug>
#include <math.h>

inline int digCount(int value)
{
    int num = 0;
    while(value != 0)
    {
        value /= 10;
        num ++;
    }
    return num;
}

/**
 * @brief round 将整数取前 dig_num 位有效数字，向零四舍五入
 * @param value
 * @param dig_num
 * @return
 */
int round(int value, unsigned int dig_num)
{
    int value_abs = (value < 0) ? -value: value;
    int sign = (value < 0) ? -1: 1;
    int num = digCount(value);

    // 到这里 value 有 num 位数字。
    int div[10] = {1, 10, 100 ,1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
    if(num > dig_num) // 这时才需要取整
    {
        dig_num = num - dig_num;
        value_abs = (value_abs + div[dig_num] / 2) / div[dig_num] * div[dig_num];
    }
    return sign * value_abs;
}


DialogCameraSetup::DialogCameraSetup(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogCameraSetup)
{
    ui->setupUi(this);
    //
    init();
    connect(ui->horizontalSliderExposureTimeIndex, SIGNAL(valueChanged(int)), this, SLOT(changeShutterIndex(int)));
    connect(ui->comboBoxAWB, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAWB(int)));
    connect(ui->horizontalSliderGain, SIGNAL(valueChanged(int)), this, SLOT(changeGain(int)));
    connect(ui->horizontalSliderBlackLevel, SIGNAL(valueChanged(int)), this, SLOT(changeBlackLevel(int)));
    connect(ui->horizontalSliderGamma, SIGNAL(valueChanged(int)), this, SLOT(changeGamma(int)));
    connect(ui->horizontalSliderContrast, SIGNAL(valueChanged(int)), this, SLOT(changeContrast(int)));
    connect(ui->horizontalSliderLightness, SIGNAL(valueChanged(int)), this, SLOT(changeLightness(int)));

    enableContrast(false);
    enableLightness(false);
}

void DialogCameraSetup::enableGain(bool on)
{
    ui->horizontalSliderGain->setEnabled(on);
}

void DialogCameraSetup::enableBlackLevel(bool on)
{
    ui->horizontalSliderBlackLevel->setEnabled(on);
}

void DialogCameraSetup::enableGamma(bool on)
{
    ui->horizontalSliderGamma->setEnabled(on);
}

void DialogCameraSetup::enableLightness(bool on)
{
    ui->horizontalSliderLightness->setEnabled(on);
}

void DialogCameraSetup::enableContrast(bool on)
{
    ui->horizontalSliderContrast->setEnabled(on);
}

void DialogCameraSetup::changeAWB(int index)
{
    switch(index)
    {
    case 1:
        emit autoWhiteBalanceChanged(1);
        //emit autoWhiteBalanceContinuous(true);
        break;
    case 2:
        emit autoWhiteBalanceOnce();
        emit autoWhiteBalanceChanged(2);
        ui->comboBoxAWB->setCurrentIndex(0);
        break;
    case 0:
    default:
        emit autoWhiteBalanceOnceOff();
        emit autoWhiteBalanceChanged(0);
        break;
    }
}

void DialogCameraSetup::changeContrast(int value)
{
    double contrast = value / 10.0;
    ui->labelContrast->setText(QString::number(contrast));
    emit contrastChanged(contrast);
}

void DialogCameraSetup::updateContrastAbs(double contrast)
{
    ui->horizontalSliderContrast->setValue(contrast * 10.0);
    ui->labelContrast->setText(QString::number(contrast));
}

void DialogCameraSetup::changeLightness(int value)
{
    double lightness = value;
    ui->labelLightness->setText(QString::number(lightness));
    emit lightnessChanged(lightness);
}

void DialogCameraSetup::updateLightnessAbs(double lightness)
{
    ui->horizontalSliderLightness->setValue(lightness);
    ui->labelLightness->setText(QString::number(lightness));
}

void DialogCameraSetup::setGammaRange(double min, double max)
{
    m_gammaRange.first = min;
    m_gammaRange.second = max;
    ui->horizontalSliderGamma->setRange(min * 10, max * 10);
}

void DialogCameraSetup::changeGamma(int value)
{
    double gamma = (value / 10.0);
    ui->labelGamma->setText(QString::number(gamma));
    emit gammaChanged(gamma);
}

void DialogCameraSetup::updateGamma(double gamma)
{
    ui->horizontalSliderGamma->setValue(gamma * 10.0);
    ui->labelGamma->setText(QString::number(gamma));
}

void DialogCameraSetup::setBlackLevelRange(double min, double max)
{
    qDebug() << "BlackLevel range :" << min << ", " << max;
    m_blackLevelRange.second = max;
    m_blackLevelRange.first = min;
    if(m_blackLevelRange.first == 0.0 && m_blackLevelRange.second == 0.0)
    {
        ui->horizontalSliderBlackLevel->setEnabled(false);
    }
    else
    {
        ui->horizontalSliderBlackLevel->setEnabled(true);
        ui->horizontalSliderBlackLevel->setRange(m_blackLevelRange.first * 10, m_blackLevelRange.second * 10);
    }
}

void DialogCameraSetup::changeBlackLevel(int value)
{
    double v = static_cast<double>(value) / 10.0;
    emit blackLevelRawChanged(value);
    emit blackLevelAbsChanged(v);
}

void DialogCameraSetup::updateBlackLevelAbs(double level)
{
    ui->horizontalSliderBlackLevel->setValue(level * 10.0);
}

void DialogCameraSetup::updateBlackLevelRaw(int level)
{
    ui->horizontalSliderBlackLevel->setValue(level);
}

void DialogCameraSetup::setGainRange(double min, double max)
{
    m_gainRange.first = min;
    m_gainRange.second = max;
    ui->horizontalSliderGain->setRange(m_gainRange.first * 10.0, m_gainRange.second * 10.0);
}

void DialogCameraSetup::updateGainAbs(double gain)
{
    ui->horizontalSliderGain->setValue(gain * 10.0);
}

void DialogCameraSetup::updateGainRaw(int gain)
{
    ui->horizontalSliderGain->setValue(gain);
}

void DialogCameraSetup::changeGain(int value)
{
    double gain = static_cast<double> (value) / 10.0;
    emit gainRawChanged(value);
    emit gainAbsChanged(gain);
}

void DialogCameraSetup::setShutterRange(double min, double max)
{
    m_exposureTimeRange.first = min;
    m_exposureTimeRange.second = max;
}

void DialogCameraSetup::changeShutterIndex(int index)
{
    double logn1 = log (m_exposureTimeRange.first);
    double logn2 = log (m_exposureTimeRange.second);
    double v = logn1 + (logn2 - logn1) / 100 * index;
    int value = round(exp(v) , 2 );
    qDebug() << "shutter value = " << value;
    ui->label_ExposureTime->setText(QString("%1 us").arg(value));
    emit exposureTimeAbsChanged(value);
}

void DialogCameraSetup::updateExposureTimeAbs(double exposure)
{
    double logn1 = log (m_exposureTimeRange.first);
    double logn2 = log (m_exposureTimeRange.second);
    double logn = log(exposure);

    double index = 100.0 / (logn2 - logn1) * (logn - logn1);
    //ui->spinBox->setValue(index);
    ui->horizontalSliderExposureTimeIndex->setValue(index);
    ui->label_ExposureTime->setText(QString("%1 us").arg(exposure));
}


void DialogCameraSetup::setCameraVendor(QString vendor)
{
    ui->label_CameraVendor->setText(vendor);
}

void DialogCameraSetup::setCameraType(QString type)
{
    ui->label_CameraType->setText(type);
}

void DialogCameraSetup::setCameraID(QString id)
{
    ui->label_CameraID->setText(id);
}

void DialogCameraSetup::setCameraResolution(int width, int height)
{
    QString str =  QString("%1 x %2").arg(width).arg(height);
    ui->labelReslution->setText(str);
}

void DialogCameraSetup::init()
{
//    GXGetFloatRange(m_hDevice, GX_FLOAT_EXPOSURE_TIME, &m_shutterRange);
    //ui->spinBox->setRange(0, 100);
    //ui->spinBox->setSingleStep(1);

    ui->horizontalSliderExposureTimeIndex->setRange(0, 100);
    ui->horizontalSliderExposureTimeIndex->setPageStep(1);
    ui->horizontalSliderExposureTimeIndex->setSingleStep(1);
}

DialogCameraSetup::~DialogCameraSetup()
{
    delete ui;
}
